package com.wondream.myframework.app.common.excel;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wondream.myframework.app.common.excel.annotation.ExcelColumn;
import com.wondream.myframework.app.common.excel.annotation.ExcelSheet;
import com.wondream.myframework.app.common.excel.annotation.Translate;
import com.wondream.myframework.app.common.excel.context.CfssPoiExporterContext;
import com.wondream.myframework.app.common.excel.function.FunctionRegister;
import com.wondream.myframework.app.common.excel.processor.RowProcessorStrategy;
import com.wondream.myframework.app.common.exception.BusinessExeceptionCode;
import com.wondream.myframework.app.common.util.JacksonUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.io.*;
import java.util.*;

/**
 * excel导出类
 */
@Slf4j
public class CfssPoiExporter {

    /**
     * 向StandardEvaluationContext中注册内部函数
     */
    static {
        FunctionRegister.registerInternalFunction();
    }

    /**
     * 导出excel
     */
    public static void export(XSSFWorkbook wb, Map<String, Object> rootObjectMap) {
        final String op = "CfssPoiExporter.export";
        long start = System.currentTimeMillis();
        CfssPoiExporterContext cfssPoiExporterContext = new CfssPoiExporterContext(new SpelExpressionParser(), rootObjectMap);
        // 分sheet进行处理
        for (int i = 0; i < wb.getNumberOfSheets(); i++) {
            XSSFSheet sheet = wb.getSheetAt(i);
            int j = sheet.getFirstRowNum();
            while (j < sheet.getLastRowNum()) {
                XSSFRow row = sheet.getRow(j);
                if (row == null) {
                    j++;
                    continue;
                }
                int dealRow = RowProcessorStrategy.getRowProcessor(row).dealRow(row, cfssPoiExporterContext);
                j = j + dealRow;
            }
        }
        long end = System.currentTimeMillis();
        log.info(String.format("%s解析模板耗时：%s", op, start - end));
    }


    /**
     * 导出到制定地方 des
     */
    public static XSSFWorkbook export2Destination(File templateFile, Map<String, Object> rootObjetMap, OutputStream des) {
        final String op = "CfssPoiExporter.export2Destination";
        InputStream in = null;
        try {
            in = new FileInputStream(templateFile);
        } catch (FileNotFoundException e) {
            log.warn(String.format("%s模板文件不存在", op));
        }
        return export2Destination(in, rootObjetMap, des);
    }

    /**
     * 导出到制定地方 des
     */
    public static XSSFWorkbook export2Destination(InputStream templateInputStream, Map<String, Object> rootObjetMap, OutputStream des) {
        final String op = "CfssPoiExporter.export2Destination";
        XSSFWorkbook wb = null;
        try {
            wb = new XSSFWorkbook(templateInputStream);
        } catch (IOException e) {
            log.warn(String.format("%s读取文件失败", op));
            throw BusinessExeceptionCode.SYS_ERROR.exp();
        }
        CfssPoiExporter.export(wb, rootObjetMap);
        // 关闭资源
        try {
            wb.write(des);
            des.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(des);
        }
        return wb;
    }

    private static class Function {
        public static Date cfssDate(String date){
            return DateTime.parse(date, DateTimeFormat.forPattern("yyyy-MM-dd")).toDate();
        }
    }

    @Data
    @ExcelSheet(sheetName="sheet1", headLine=1, classType=DataInfo.class)
    private static class DataInfo {
        @ExcelColumn("产品名称")
        private String productName;
        @ExcelColumn("产品类型")
        private String productType;
        @ExcelColumn("客户名称")
        private String customerName;
        @ExcelColumn("时间")
        @Translate(cls = Function.class, value = "cfssDate")
        private Date date;
        @ExcelColumn("时间")
        private String dateStr;
    }

    public static void importTest(){
        List<Class> entityCls = Lists.newArrayList(DataInfo.class);
        Map<Class, List> datas = CfssPoiImporter.importExcel("./temp/data.xlsx", entityCls);
        List<DataInfo> dataInfos = datas.get(DataInfo.class);
        System.out.println(JacksonUtil.toJson(dataInfos));
    }

    public static void main(String[] args) {
        InputStream templateInputStream;
        try {
            templateInputStream = new FileInputStream("./temp/template.xlsx");
            Map<String, Object> rootObjectMap = Maps.newHashMap();
            List<DataInfo> dataList = Lists.newArrayList();
            DataInfo dataInfo = new DataInfo();
            dataInfo.setCustomerName("张三");
            dataInfo.setProductName("产品1");
            dataInfo.setProductType("1");
            dataInfo.setDate(new Date());
            dataList.add(dataInfo);
            rootObjectMap.put("dataList", dataList);
            FileOutputStream dest = new FileOutputStream("./temp/data.xlsx");
            CfssPoiExporter.export2Destination(templateInputStream, rootObjectMap, dest);
            importTest();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
